package Market;


import java.util.*;

import edu.iastate.jrelm.rl.SimpleStatelessLearner;
import sim.engine.*;


public class Market extends SimState{
	
	private static final long serialVersionUID = 6628525522939315274L;
												
												/** Priorities counter to fire agents in a chosen order */
	  private int count = 0;
												/** Number of Branches*/
	  public int N=5;	  
	  											/** Number of Nodes*/
	  public int K=5;
	  											/** Boolean used to separate GenCo's methods execution  */
//	  boolean Switch;
	  											/** Number of days of market operation */	  	  
// GenCo												
												/** Number of GenCos */
	  public int I=5;
	  											/** GenCos location at node  */
	  private int[] GenCoAtNode;
	  											/** GenCos list */
	  private ArrayList GenCoList;
	  											/** Action domains list */
	  private ArrayList ADList;
	  											/** Learners list */
	  private ArrayList<SimpleStatelessLearner<?>> LearnerList;
	  											/** GenCo's Data: {Gen ID, at Node, FCost, aT, bT, CapTL, CapTU, Initial Money in pounds} */
	  private double[][] GenCoData;
	  											/** Learning Data: {initial propensity, Cooling, Recency, Experimentation, M1, M2, M3, RIMaxL, RIMaxU, RIMinC, SlopeStart, Reward Selection} */
	  private double[][] LearningData;
	  											/** True Supply Offer: {aT,bT,CapTL,CapTU} */
	  private double[][] TSupplyOffer;
	  											/** Reported Supply Offer: {aR,bR,CapRL,CapRU} */
	  private double[][] RSupplyOffer;
	  											/** Hourly power production quantity by GenCos */
	  
	  
	  public Hashtable<String, Object> lmpAtHour = new Hashtable<String, Object>() ;
	  public Hashtable<String, Object> commitment = new Hashtable<String, Object>() ;
	  
	  // public Hashtable<String, Double> lmpAtNode = new Hashtable<String, Double>() ;
	 // public Hashtable<String, Double> lmpNode3 = new Hashtable<String, Double>() ;
	  //public Hashtable<String, Double> lmpNode4 = new Hashtable<String, Double>() ;
	  //public Hashtable<String, Double> lmpNode5 = new Hashtable<String, Double>() ;
	  
	  //  public double[][] Commitment;
	  											/** GenCo's accumulative money holding, money (new) = money(previous) + dailyProfit(new) */
	  public double genCoMoney;
	  
	  SimpleStatelessLearner Learner;	  
												/** list of GenCos */
	  public Hashtable<String, GenCo> genCoList = new Hashtable<String, GenCo>() ;
	  //public Hashtable<String, Initials.InitBranch> branchList = new Hashtable<String, Initials.InitBranch>() ;
	  public Hashtable<String, Object> branchList = new Hashtable<String, Object>() ;
// LSE
												/** Number of LSEs */
	  public int J=3;
	  											/** LSEs location at node  */
	  //private int[] LSEAtNode;
	  											/** LSE's Data: {LSE ID, at Node, L(0), L(1),L(2),L(3),L(4), ...,L(23)} */
	 // private double[][] LSEData;
	  											/** LSE's list */
	 // private ArrayList LSEList;    
	  											/** LSE's load profile for each hour [Hour][LSE] */
	//  private double[][] LoadProfile;
	  											/** Twenty-four hours */
	  public final int Hours = 24;
	  											/** list of LSEs */
	  public Hashtable<String, LSE> lseList = new Hashtable<String, LSE>() ;
// ISO
	  											/** Local marginal price for each hour and node [Hour][Node] */
	  private double [][] LMP;
	  											/** Current day */  
	  public static int D;
	  public Hashtable<String, Object> reportedSupplyOffer = new Hashtable<String, Object>();
	  public Hashtable<String, Hashtable> electricityDemand = new Hashtable<String, Hashtable>();
	  public Hashtable<String, Double> nodeData = new Hashtable<String, Double>() ;
//C-O-N-S-T-R-U-C-T-O-R------------------------------------------------------------------------------------------------------------------------------  


	    public Market(long seed)
	        {
	        super(seed);
	        }
	//-----------------------------------------------------------------
	    

	    public void start()
	        {
	        super.start();
	  
	  
	  
	  
	  
	  
    	  
    	Initials.InitGenCo  initG = new Initials.InitGenCo(this);
      	Initials.InitLSE    initL = new Initials.InitLSE(this);
      	Initials.InitBranch initB = new Initials.InitBranch(this);
      	Initials.InitNode   initN = new Initials.InitNode(this);
      	ElGrid elgrid             = new ElGrid();
      	
      	// Check this !!!!!!!!!!!!!
      	

      
      	

      
//----GenCo------------------------------------------------             	       	

      	
/* ********* Money update needs to be fixed***************************************
	
      	        if (d>0){		
             		  for (int i=0;i<I;i++){               			
          		  GenCoData[i][7]= getGenCoMoney()[i];
          		  }	
      	        }
***************************************************************************/        	
      	GenCo gen  = null;
      	
      	for(int i=0; i<I; i++){
      		int id = i+1;      		     		
      		gen = genCoList.get("genco"+id);    		 		
            gen.Switch = false;     		     		
      		this.schedule.scheduleRepeating(gen, 0, 1d);   

      		//reportedSupplyOffer.put("genco"+id, gen.reportedSupplyOffer);     		
      		//elgrid.addGenCoAtNodeK(gen, gen.node);                		
      	}    
      	
      	
//----- LSE-------------------------------------------------     
 	
      	for(int j=0; j<J; j++){
      		int id = j+1;
      		LSE lse = lseList.get("lse"+id); 				
      		this.schedule.scheduleRepeating(lse, 1, 1d);	     		
      		//electricityDemand.put("lse"+id, lse.electricityDemand);
      		
      		elgrid.addLSEAtNodeK(lse, lse.node);                        	
      		}
      	
//----- ISO-------------------------------------------------     	

      		ISO iso = new ISO(this);
      		this.schedule.scheduleRepeating(iso, 2, 1d);		
   
	        }    
//----- GenCo----------------------------------------------           
      		        		 
	 		//for(int i=0; i<I; i++){ 
	 		//	int id = i+1;
	 		//	gen = genCoList.get("genco"+id);      		
	 		//	gen.Switch = true;
	 		//	gen.day = D;

	 			//schedule.scheduleOnce(gen, 3); 
	 		//}
	 	//}
    	  
	  

//-------M-A-I-N---------------------------------------------------------------------------------------
     public static void main(String[] args){
          Market market = new Market(System.currentTimeMillis());       
          market.start();
          long jobsMax=5;
          int stepMax=365;
          for (int jobs=0; jobs<=jobsMax-1; jobs++)
  	      {
        	  System.out.println("======simulation======"+jobsMax);
        	  market.start();
          	do
    		{
          		if (!market.schedule.step(market))
   			   {
   				   System.err.println("Error with the step function of the AWEM model");
   				   break;
   			   }
          		//end of step
          		market.updateAgents();
          	 	System.out.println("======days======"+market.schedule.getSteps());
          	  } 
    		  while (market.schedule.getSteps() < stepMax-1);
          	
  	      	}
                  
          System.out.println("Done!!!");
          market.finish();
          System.exit(0);
      }
  
//----- Set and Get methods------------------------------------------------------------------------   

 //   /** Adds LSEs to the list */   
 //   public void setLSEList(Object lselist)
 //   {
 //   	LSEList.add(lselist);   	
 //   }
//-------------------------------------------------------------------------------------------------    
   
  //  /** Sets LSE's load profile for every hour and every LSE */ 
  //  public void SubmitLoadProfile(double loadprofile, int h, int jj){
  //  	LoadProfile[h][jj] = loadprofile;
  //  } 
 //-------------------------------------------------------------------------------------------------    
   // /** Returns hourly load profiles */   
   // public double[][] getLoadProfile(){
   // 	return LoadProfile;
   // }
//-------------------------------------------------------------------------------------------------    
    
    public void  updateAgents()
    {
    	//add update profit + learn
    	
    }
     
     
    /** Sets true supply offer for each GenCo */ 
    public void setTSupplyOffer(double[] tsupplyoffer, int g){
    	for (int i=0; i<4; i++){
    		TSupplyOffer[g][i] = tsupplyoffer[i]; 	
    	}
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Sets reported supply offer for each GenCo */
    public void setRSupplyOffer(double[] rsupplyoffer, int g){
    	for (int i=0; i<4; i++){
    		RSupplyOffer[g][i] = rsupplyoffer[i]; 	
    	}
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Returns reported supply offer */
    public double[][] getRSupplyOffer(){
    	return RSupplyOffer;
    }
    
//-------------------------------------------------------------------------------------------------    
   
    /** Returns true supply offer */
    public double[][] getTSupplyOffer(){
    	return TSupplyOffer;
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Adds action domains to the list */
    public void addAactionDomain(ArrayList adlist){    	
    	ADList.add(adlist);
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Sets Learner */
    public void setLearnerList(SimpleStatelessLearner learner){    	
    	LearnerList.add(learner);
    	System.out.println("Seted");
    }
//-------------------------------------------------------------------------------------------------    
   
    /** Adds GenCos to the list */
    public void addGenCo(Object genco){    	
    	GenCoList.add(genco);
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Returns GenCos' list */
    public ArrayList getGenCo(){    	
    	return GenCoList;
    }
//-------------------------------------------------------------------------------------------------    
    
    /** Sets LMP list for each hour and node */
    public void setLMPList(double[] lmp, int h ){    	 	
    	for (int i=0; i<K; i++){
    		LMP[h][i] = lmp[i];
    	}
    }
//-------------------------------------------------------------------------------------------------    
    
  //  /** Sets boolean Switch */
 //   public void setSwitch(boolean sw){    	
 //   	Switch = sw;
 //   }
//-------------------------------------------------------------------------------------------------    
    
 //   /** Returns boolean Switch */
  //  public boolean getSwitch(){
  //  	return Switch;
  //  }
//-------------------------------------------------------------------------------------------------    
    /** Sets hourly power production quantity for each GenCo */
   // public void setCommitment(double[] commitment, int h ){   	 
   // 	for (int i=0; i<I; i++){
   // 		Commitment[h][i] = commitment[i];
   // 	}
   // }
//-------------------------------------------------------------------------------------------------    
 //   /** Returns hourly power production quantity by GenCos  */
 //   public double[][] getCommitment(){
 //   	return Commitment;	
 //   }
//-------------------------------------------------------------------------------------------------    
    
    /** Returns LMP */
    public double[][] getLMP(){
    	return LMP;	
    }
//-------------------------------------------------------------------------------------------------    
 
 //   /** Sets accumulative money holding for each GenCo*/
//	public void setGenCoMoney(int i, double gencomoney){
//		GenCoMoney[i] = GenCoMoney[i]+gencomoney;		
		//if (i==0){
		//System.out.println(GenCoMoney[i]);}
		//System.out.println("i= "+i+" "+GenCoMoney[i]+"   "+gencomoney[i]);
//	}
//-------------------------------------------------------------------------------------------------    

	///** Returns GenCo's accumulative money holding*/
//	public double[] getGenCoMoney(){		
	//	return GenCoMoney;
	//}
//-------------------------------------------------------------------------------------------------    

	
	
	
	
	
}
